home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
STANDALO
/
SPROING!
/
SPROING_.C
next >
Wrap
C/C++ Source or Header
|
1990-10-27
|
4KB
|
147 lines
/*_________________________________________________________________________
Sproing - A Springy Cursor VBL
October 1990
⌐1990 Scott Armitage
Written for Think C
This VBL will put values into the MouseOffset system global to cause
the mouse to move relative to its normal position.
The offset used here is a filtered version of the mouse's position.
This gives a "springy" effect to the cursor movement.
Depressing the Caps Lock key will disable the filtering action.
This code uses undocumented system globals and could break someday,
but, hey, what's a good hack that doesn't live a bit dangerously?
Floating point cannot be used here, apparently because the FP68K
trap is not reentrant (i.e. when an application does a SANE operation
and the VBL interrupts it and does a SANE operation too... KaBoom).
To circumvent this and still get smooth filtering action,
all mouse locations are expressed in fixed point format.
This VBL can be installed with an INIT or with an installer application.
_________________________________________________________________________*/
#include "VRetraceMgr.h"
/* the system globals we use */
extern Boolean CrsrNew : 0x8CE;
extern Point MouseOffset : 0x8DA;
extern Point mTemp : 0x828;
extern char keyMap[8] : 0x174;
/* some constants for adjusting dynamics */
/* slugishness (10=quick, 1000=painfully slow) */
#define slugishness 50
/* offset per movement of cursor (1 = dull, 100 = touchy) */
#define sensitivity 10
/* our globals */
Fixed newX, newY;
Fixed vx, vy;
unsigned long me;
/* function prototypes */
header(void);
__GetA4(void);
main(void);
getNewOffset(int* x, int* y);
/*_____________________________________________________________________*/
/* our custom header */
header()
{
asm {
dc.l 0 /* a place to store A4 */
move.l a0, d0 /* save a0 (vbl ptr) */
lea header, a0 /* for SetUpA4() */
jmp main
}
}
#include "SetUpA4.h"
/*_____________________________________________________________________*/
main()
{
VBLTask* myVBL;
int xOfs, yOfs;
RememberA0(); /* save a0 */
SetUpA4(); /* set a4 */
asm {
move.l d0, myVBL /* a ptr to vbl task */
}
if (me != 'Scot') { /* first time ? */
newX = Long2Fix(mTemp.h); /* init globals */
newY = Long2Fix(mTemp.v);
vx = 0;
vy = 0;
me = 'Scot';
}
/* test caps lock key - GetKeys can't be used in a VBL */
if (keyMap[7] & 0x02) { /* caps lock down ? */
newX = Long2Fix(mTemp.h); /* restore things to normal */
newY = Long2Fix(mTemp.v);
vx = 0;
vy = 0;
MouseOffset.h = 0;
MouseOffset.v = 0;
CrsrNew = true;
}
else { /* caps lock up */
getNewOffset(&xOfs, &yOfs); /* do our filtering */
MouseOffset.h = xOfs; /* use our mouse offset correction */
MouseOffset.v = yOfs;
CrsrNew = true; /* tell 'em we changed it */
}
myVBL->vblCount = 1; /* see ya' next time */
RestoreA4();
}
/*_____________________________________________________________________
This routine computes a new offset for the cursor.
It uses a "rubber band" model.
It first factors in the velocity of the cursor to give the
illusion of inertia. Then it computes the distance
from the "real" cursor position to the offset position.
This distance is used to compute the force which the rubber
band exerts to pull the cursor back into position.
_____________________________________________________________________*/
getNewOffset(xOfs, yOfs)
int *xOfs, *yOfs;
{
Fixed oldX, oldY, deltaX, deltaY, xOffset, yOffset;
oldX = newX; /* save old locations */
oldY = newY;
newX += vx; /* add effect of inertia */
newY += vy;
deltaX = newX - Long2Fix(mTemp.h); /* find distance to real cursor */
deltaY = newY - Long2Fix(mTemp.v);
/* add force proportional to distance */
xOffset = - sensitivity * deltaX / 10;
yOffset = - sensitivity * deltaY / 10;
newX += xOffset/slugishness; /* adjust how much we'll respond */
newY += yOffset/slugishness; /* to the force */
vx = newX - oldX; /* get velocity for next time */
vy = newY - oldY;
*xOfs = Fix2Long(xOffset); /* return the answers */
*yOfs = Fix2Long(yOffset);
}